﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using ControleRepresentanteSync.Application.SimpleSync;
using ControleRepresentanteSync.Logic;

namespace ControleRepresentanteSync.View.SimpleSync
{
    internal abstract class SimpleSyncContentViewModel<TModel, TItem, TContract> : ViewModelBase, ISimpleSyncContentViewModel<TModel, TItem, TContract>
        where TItem : ISimpleSycItem<TContract>
    {
        public static readonly DependencyProperty IsCheckedProperty =
            DependencyProperty.Register("IsChecked", typeof(bool), typeof(SimpleSyncContentViewModel<TModel, TItem, TContract>), new PropertyMetadata(OnIsCheckedChanged));
        public static readonly DependencyProperty ActionProperty =
            DependencyProperty.Register("Action", typeof(SyncAction), typeof(SimpleSyncContentViewModel<TModel, TItem, TContract>), new PropertyMetadata(OnActionChanged));
        public static readonly DependencyProperty TargetProperty =
            DependencyProperty.Register("Target", typeof(TItem), typeof(SimpleSyncContentViewModel<TModel, TItem, TContract>), new PropertyMetadata(OnTargetChanged));
        public static readonly DependencyProperty IsValidProperty =
            DependencyProperty.Register("IsValid", typeof(bool), typeof(SimpleSyncContentViewModel<TModel, TItem, TContract>), new PropertyMetadata(OnIsValidChanged));

        private readonly ObservableCollection<SyncAction> m_Actions;
        private readonly ObservableCollection<TItem> m_Targets;
        public TModel Model { get; set; }

        protected SimpleSyncContentViewModel()
        {
            m_Actions = new ObservableCollection<SyncAction>();
            m_Targets = new ObservableCollection<TItem>();
        }

        public bool IsChecked
        {
            get { return (bool) GetValue(IsCheckedProperty); }
            set { SetValue(IsCheckedProperty, value); }
        }

        public SyncAction Action
        {
            get { return (SyncAction)GetValue(ActionProperty); }
            set { SetValue(ActionProperty, value); }
        }

        public TItem Target
        {
            get { return (TItem)GetValue(TargetProperty); }
            set { SetValue(TargetProperty, value); }
        }

        public bool IsValid
        {
            get { return (bool) GetValue(IsValidProperty); }
            set { SetValue(IsValidProperty, value); }
        }

        public IList<SyncAction> Actions { get { return m_Actions; } }
        public IList<TItem> Targets { get { return m_Targets; } }

        private static void OnActionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((SimpleSyncContentViewModel<TModel, TItem, TContract>)d).FireActionChanged();
        }

        private void FireActionChanged()
        {
            if (ActionChanged != null)
                ActionChanged(this, EventArgs.Empty);
        }

        private static void OnIsValidChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((SimpleSyncContentViewModel<TModel, TItem, TContract>)d).FireIsValidChanged();
        }

        private void FireIsValidChanged()
        {
            if (IsValidChanged != null)
                IsValidChanged(this, EventArgs.Empty);
        }

        private static void OnTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((SimpleSyncContentViewModel<TModel, TItem, TContract>)d).FireTargetChanged();
        }

        private void FireTargetChanged()
        {
            if (TargetChanged != null)
                TargetChanged(this, EventArgs.Empty);
        }

        private static void OnIsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((SimpleSyncContentViewModel<TModel, TItem, TContract>)d).FireIsCheckedChanged();
        }

        public event EventHandler IsCheckedChanged;

        private void FireIsCheckedChanged()
        {
            if (IsCheckedChanged != null)
                IsCheckedChanged(this, EventArgs.Empty);
        }

        public event EventHandler IsValidChanged;
        public event EventHandler TargetChanged;
        public event EventHandler ActionChanged;
    }
}